<template>
  <div class="container">
    <div class="panel">
      <el-button @click="add3DStyle2">添加立体样式(canvas阴影)</el-button>
      <el-button @click="add3DStyle3">添加立体样式(图形堆叠)</el-button>
      <el-button @click="clear">清空</el-button>
    </div>
  </div>
  <div id="mapContainer"></div>
  <!-- <base-map :center="[119.5408657586792, 32.92253513378263]" :zoom="7" /> -->
</template>

<script setup>
import { onMounted, nextTick } from "vue";

import { Map, View } from "ol";
import { transform } from "ol/proj";

import {
  Tile as TileLayer,
  Vector as VectorLayer,
  Image as ImageLayer,
  VectorTile as VectorTileLayer,
} from "ol/layer";
import {
  XYZ,
  Vector as VectorSource,
  ImageCanvas,
  VectorTile as VectorTileSource,
} from "ol/source";

import { GeoJSON, MVT } from "ol/format";

import Feature from "ol/feature";
import { Point, LineString, Polygon, Circle } from "ol/geom";

import { Style, Stroke, Circle as CircleStyle, Fill } from "ol/style";

import { tdt_api_key /** 天地图的key */ } from "@/config/keys.json";
import { addTdtBaseLayer } from "@/utils/baseMap.js";

import { getExtent } from "@/utils/view.js";
import { removeLayerBy } from "@/utils/layer.js";

function initMap() {
  const map = new Map({
    view: new View({
      projection: "EPSG:4326",
      center: [119.5408657586792, 32.92253513378263],
      zoom: 8,
      constrainResolution: true,
    }),
    target: "mapContainer",
    controls: [],
  });

  window.map = map;

  addTdtBaseLayer(map, tdt_api_key, "vec", "c", "wmts");
  addJSLayer(),
    //地图点击事件
    map.on("click", e => {
      console.log("click", e.coordinate);
      console.log("zoom", map.getView().getZoom());
    });
}

onMounted(() => {
  nextTick(() => {
    initMap();
  });
});

let jsLayer;
function addJSLayer() {
  jsLayer = new VectorLayer({
    source: new VectorSource({
      url: "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=320000",
      format: new GeoJSON(),
    }),
    style: function (feature) {
      const style = new Style({
        stroke: new Stroke({
          color: "red",
          width: 5,
        }),
      });
      return style;
    },
  });

  window.map.addLayer(jsLayer);
}

// function add3DStyle1() {
//   jsLayer.setStyle(
//     new Style({
//       renderer: function (coordinate, state) {
//         let arr = coordinate[0][0];
//         const ctx = state.context;

//         addOutlineShadow(ctx, {
//           fillStyle: "rgba(30, 60, 95,1)",
//           shadowOffsetY: 30,
//           shadowOffsetX: 2,
//           shadowColor: "rgba(30, 60, 95,1)",
//           strokeStyle: "rgba(30, 60, 95,1)",
//           coodArr: arr,
//         });

//         addOutlineShadow(ctx, {
//           fillStyle: "transparent",
//           shadowOffsetY: 20,
//           shadowOffsetX: 2,
//           shadowColor: "rgba( 56, 113, 139,1)",
//           strokeStyle: "rgba(30, 60, 95,1)",
//           coodArr: arr,
//         });
//         addOutlineShadow(ctx, {
//           fillStyle: "transparent",
//           shadowOffsetY: 15,
//           shadowOffsetX: 2,
//           shadowColor: "rgba(255,255,255,1)",
//           strokeStyle: "rgba(30, 60, 95,1)",
//           shadowBlur: 10,
//           coodArr: arr,
//         });
//         addOutlineShadow(ctx, {
//           fillStyle: "transparent",
//           shadowOffsetY: 10,
//           shadowOffsetX: 2,
//           shadowColor: "rgba(83, 173, 214,1)",
//           strokeStyle: "rgba(83, 173, 214,1)",
//           coodArr: arr,
//         });
//         addOutlineShadow(ctx, {
//           fillStyle: "transparent",
//           shadowOffsetY: 8,
//           shadowOffsetX: 2,
//           shadowColor: "rgba(255,255,255,1)",
//           strokeStyle: "rgba(255,255,255,1)",
//           shadowBlur: 10,
//           coodArr: arr,
//         });
//         addOutlineShadow(ctx, {
//           fillStyle: "#fff",
//           shadowOffsetY: 5,
//           shadowOffsetX: 2,
//           shadowColor: "rgba(70, 133, 171,1)",
//           strokeStyle: "rgba(70, 133, 171,1)",
//           shadowBlur: 10,
//           coodArr: arr,
//         });
//         // 白色
//         addOutlineShadow(ctx, {
//           fillStyle: "rgba(70, 133, 171,1)",
//           shadowOffsetY: 5,
//           shadowOffsetX: 10,
//           shadowColor: "rgba(255,255,255,1)",
//           shadowBlur: 15,
//           coodArr: arr,
//           strokeStyle: "#50e3ff",
//           lineWidth: 2,
//         });
//       },
//     })
//   );
// }

function add3DStyle2() {
  const jsCanvasLayer = new VectorLayer({
    properties: {
      id: "js_canvasLayer",
    },
    source: new VectorSource({
      url: "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=320000",
      format: new GeoJSON(),
    }),
    style: function (feature) {
      const style = new Style({
        stroke: new Stroke({
          color: "red",
          width: 5,
        }),
      });
      return style;
    },
  });

  window.map.addLayer(jsCanvasLayer);

  const colors = [
    "rgba(83, 112, 137, 1)",
    "rgba(106, 125, 144, 1)",
    "rgba(129, 138, 151, 1)",
    "rgba(152, 151, 158, 1)",
    "rgba(175, 164, 165, 1)",
    "rgba(198, 177, 172, 1)",
    "rgba(221, 190, 179, 1)",
    "rgba(244, 203, 186, 1)",
    "rgba(255, 216, 193, 1)",
    "rgba(255, 229, 200, 1)",
  ];

  jsCanvasLayer.setStyle(
    new Style({
      renderer: function (coordinate, state) {
        let arr = coordinate[0][0];
        const ctx = state.context;

        ctx.filter = "contrast(1.4) brightness(180%) ";

        colors.forEach((color, index) => {
          addOutlineShadow(ctx, {
            fillStyle: "transparent",
            shadowOffsetY: 30 - index * 3,
            shadowOffsetX: 2,
            shadowColor: color,
            strokeStyle: color,
            coodArr: arr,
          });
        });

        addOutlineShadow(ctx, {
          fillStyle: "#fff",
          shadowOffsetY: -5,
          shadowOffsetX: -7,
          shadowColor: "rgba(255,255,255,1)",
          strokeStyle: "red",
          shadowBlur: 5,
          coodArr: arr,
        });
        // 白色 #0F1C2D
        addOutlineShadow(
          ctx,
          {
            fillStyle: "rgba(  29, 42, 62,0.4)",
            shadowOffsetY: 5,
            shadowOffsetX: 7,
            shadowColor: "rgba(255,255,255,1)",
            shadowBlur: 5,
            coodArr: arr,
            strokeStyle: "#50e3ff",
            lineWidth: 5,
          },
          true
        );
      },
    })
  );
}

function addOutlineShadow(ctx, option, isFill = false) {
  // 设置属性控制图形的外观
  ctx.fillStyle = option.fillStyle || "transparent";
  ctx.strokeStyle = option.strokeStyle || "transparent";
  ctx.lineWidth = option.lineWidth || 1;

  //  设置Y轴偏移量
  ctx.shadowOffsetY = option.shadowOffsetY || 20;
  //  设置X轴偏移量
  ctx.shadowOffsetX = option.shadowOffsetX || 2;
  //  设置模糊度
  ctx.shadowBlur = option.shadowBlur || 2;
  //  设置阴影颜色
  ctx.shadowColor = option.shadowColor || "#000";
  ctx.beginPath();
  let arr = option.coodArr || [];
  for (let i = 0; i < arr.length; i++) {
    const data = arr[i];
    if (i === 0) {
      ctx.moveTo(data[0], data[1]);
    } else {
      ctx.lineTo(data[0], data[1]);
    }
  }
  ctx.closePath();
  isFill && ctx.fill();
  ctx.stroke();
}

function add3DStyle3() {
  const source = jsLayer.getSource();
  const coordinates = source
    .getFeatures()[0]
    .getGeometry()
    .getCoordinates()[0][0];

  const colors = [
    "rgba(83, 112, 137, 0.1)",
    "rgba(106, 125, 144, 1)",
    "rgba(129, 138, 151, 1)",
    "rgba(152, 151, 158, 1)",
    "rgba(175, 164, 165, 1)",
    "rgba(198, 177, 172, 1)",
    "rgba(221, 190, 179, 1)",
    "rgba(244, 203, 186, 1)",
    "rgba(255, 216, 193, 1)",
    "rgba(255, 229, 200, 1)",
  ].reverse();

  let offsetX = -0.01;
  let offsetY = -0.015;
  const features = [];

  for (let index = colors.length - 1; index >= 0; index--) {
    const color = colors[index];
    const newCoordinates = coordinates.map(coordinate => {
      return [
        coordinate[0] + offsetX * (index + 1),
        coordinate[1] + offsetY * (index + 1),
      ];
    });

    const feature = new Feature({
      geometry: new Polygon([newCoordinates]),
    });
    feature.setStyle(
      new Style({
        fill: new Fill({
          color: color,
        }),
      })
    );

    features.push(feature);
  }

  const shadowLayer = new VectorLayer({
    properties: {
      name: "江苏立体阴影图层",
      id: "js_shadowLayer",
    },
    source: new VectorSource({
      features: features,
    }),
    zIndex: 2,
  });

  window.map.addLayer(shadowLayer);

  const originalFeature = source.getFeatures()[0];

  const originLayer = new VectorLayer({
    properties: {
      name: "江苏行政区划边界",
      id: "js_originLayer",
    },
    source: new VectorSource({
      features: [originalFeature],
    }),
    style: new Style({
      fill: new Fill({
        color: "rgba(  29, 42, 62,1)",
      }),
      stroke: new Stroke({
        color: "#50e3ff",
        width: 5,
      }),
    }),
    zIndex: 3,
  });

  window.map.addLayer(originLayer);
}

function clear() {
  window.map.removeLayer(jsLayer);

  removeLayerBy(
    window.map,
    layer =>
      layer.id === "js_shadowLayer" ||
      layer.id === "js_originLayer" ||
      layer.id === "js_canvasLayer"
  );
}



// 工具方法

</script>

<style lang="less" scoped>
#mapContainer {
  width: 100%;
  height: 99vh;
}
.container {
}

.panel {
  position: absolute;
  top: 10px;
  left: 150px;
  z-index: 999;
}
</style>
